package com.TTBook.utils.image;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ImageUtils {
	private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);
	
	/**
	 * 将图片写进磁盘
	 * @param img 图片数据流
	 * @param path 文件保存路径
	 */
	public void writeImageToDisk(byte[] img , String path)
	{
		try {
			logger.info("begin to write the img to local disk,path-->"+path);
			File file = new File(path);
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(img);
			fos.flush();
			fos.close();
		} catch (Exception e) {
			logger.error("write the image to disk error!!",e);
		}
	}
	
	public byte[] getImageFromNetByUrl(String imgUrl)
	{
		try {
			URL url = new URL(imgUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5*1000);
			InputStream isStream = conn.getInputStream();
			byte[] btImg = readInputStream(isStream);
			conn.disconnect();
			return btImg;
		} catch (Exception e) {
			logger.error("get the image by url error !",e);
		}
		return null;
	}

	private byte[] readInputStream(InputStream isStream) throws Exception
	{
		ByteArrayOutputStream outStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ( (len=isStream.read(buffer)) != -1)
		{
			outStream.write(buffer, 0, len);
		}
		isStream.close();
		return outStream.toByteArray();
	}
	/**
	 * 读取图片文件，返回图片对象
	 * @param imageData
	 * @return
	 * @throws Exception
	 */
	
	public BufferedImage readImage(byte[] imageData) throws Exception
	{
		BufferedImage bimage = this.checkIsRGB(imageData);
		if(bimage != null) return bimage;
		Image image = new ImageIcon(imageData).getImage();
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		try {
			int transparency = Transparency.OPAQUE;
			GraphicsDevice gs = ge.getDefaultScreenDevice();
			GraphicsConfiguration gc = gs.getDefaultConfiguration();
			bimage = gc.createCompatibleImage(
					image.getWidth(null), image.getHeight(null), transparency);
			
		} catch (HeadlessException e) {
			logger.error("read the imge to buffer error.."+e);
		}
		if(bimage == null)
		{
			int type = BufferedImage.TYPE_INT_BGR;
			bimage = new BufferedImage(image.getWidth(null),image.getHeight(null),type);
		}
		Graphics g = bimage.createGraphics();
		g.drawImage(image, 0, 0, null);
		g.dispose();
		return bimage;
	}
	/**
	 * 检查图片是否为RGB
	 * @param imageData
	 * @return
	 * @throws Exception
	 */
	private BufferedImage checkIsRGB(byte[] imageData) throws Exception{
		try {
			BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageData));
			if( img != null)
			{
				int colorSpaceType = img.getColorModel().getColorSpace().getType();
				if( colorSpaceType != ColorSpace.TYPE_RGB)
				{
					BufferedImage rgbImage = 
							new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
					ColorConvertOp op = new ColorConvertOp(null);
					op.filter(img, rgbImage);
					return rgbImage;
				}
			}
		} catch (Exception e) {
			logger.error("can not read the image , please check the image format ..",e);
			throw new Exception("图片格式不正确,请检查是否为RGB格式");
		}
		return null;
	}
	/**
	 * 读取指定图像文件的色彩空间并返回
	 * @param source 要读取的图像
	 * @return	该图像文件的色彩空间
	 * @throws Exception
	 */
	private static int readImageColorModel(String source) throws Exception
	{
		if( source == null || source.length() == 0)
		{
			throw new Exception("图像文件路径不能为空。");
		}
		File file = new File(source);
		if(!file.exists())
		{
			throw new Exception("文件"+source+"不存在");
		}
		BufferedImage bi = ImageIO.read(file);
		ColorModel cm = bi.getColorModel();
		int type = BufferedImage.TYPE_3BYTE_BGR;
		if(cm.hasAlpha())
		{
			type = BufferedImage.TYPE_4BYTE_ABGR;
		}
		return type;
	}
	/**
	 * 缩放图片，如果不是等比例缩放，用白色背景补齐两边空白处
	 * @param image
	 * @param width
	 * @param height
	 * @param fillColor
	 * @return
	 * @throws Exception
	 */
	private BufferedImage scaleFillSpace(BufferedImage image , 
			int width,int height,Color fillColor)throws Exception
		{
			BufferedImage imageScale = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);
			Graphics graphics = imageScale.getGraphics();
			graphics.setColor(fillColor);
			graphics.fillRect(0, 0, width, height);
			
			//图片偏移量 --图片采用居中对齐
			int xOffset = 0;
			int yOffset = 0;
			int dWidth = width;
			int dHeight = height;
			if(width/image.getWidth()<height/image.getHeight())
			{
				dHeight = width/image.getWidth()*image.getHeight();
				yOffset = (height-dHeight)/2;
			}else if(width/image.getWidth()>height/image.getHeight())
			{
				dWidth = height/image.getHeight()*image.getWidth();
				xOffset = (width-dWidth)/2;
			}else{};
			graphics.drawImage(image.getScaledInstance(dWidth, dHeight, Image.SCALE_SMOOTH), xOffset, yOffset, null);
			return imageScale;
			
		}
	private void writeImage(BufferedImage image , String destFile , float quality)throws IOException
	{
		ImageIO.write(image, "JPEG", new File(destFile));
	}
	public void compress(BufferedImage bufferedImage ,String imagePath)
	{
		try {
			int width = bufferedImage.getWidth();
			int height = bufferedImage.getHeight();
			if(width != height || width >1200 || height > 1200)
			{
				if(width > 1200 || height > 1200)
				{
					width = 1200;
					height = 1200;
				}
				else
				{
					if(width > height) height = width;
					else width = height;
				}
				BufferedImage scaleImage = this.scaleFillSpace(bufferedImage, width, height, Color.WHITE);
				this.writeImage(scaleImage, imagePath, 0.75f);
			}
			else
			{
				this.writeImage(bufferedImage, imagePath, 0.75f);
			}
		} catch (Exception e) {
			logger.error("image compression error..imagePath-->"+imagePath+"",e);
		}
	}
}
